// A sample player implemented in C++.  The sled just marches across
// the middle trying to capture pucks.  The bumpers try to push the
// pucks toward the center so they can be captured.
//
// ICPC Challenge
// Sturgill, Baylor University

#include "Util.h"
#include <vector>
#include <iostream>
#include <list>
#include <math.h>

using namespace std;

#define LEFT 1
#define RIGHT -1
#define BIGGEST_R 96.0
#define PI 3.141592654
#define NOTHING	0
#define CHANGE_DIRECTION 1
#define CIRCLE 2
#define CIRCLE_ENDED 3
#define GETTING_AWAY_EDGE 4

/** Simple representation for a puck. */
struct Puck {
				// Position of the puck.
				Vector2D pos;

				// Puck velocity
				Vector2D vel;

				// Puck color
				int color;
};

/** Simple representation for a bumper. */
struct Bumper {
				// Position of the bumper.
				Vector2D pos;

				// Bumper velocity
				Vector2D vel;
};

/** Simple representation for a sled. */
struct Sled {
				// Position of the sled.
				Vector2D pos;

				// Sled direction.
				double dir;
};

struct Bloco {
				int Peso;
};

// List of current sled, bumper and puck locations.  These are
// updated on every turn snapshot from the server.
vector< Puck > plist;
vector< Bumper > blist;
vector< Sled > slist;
vector< vector< Vector2D > > sHist;
int sledState = 0;
double sledDir;

// State of each bumper.
enum BumperState 
{
				MoveOponent,
				SpreadGray,
				SearchBlock,
				SpreadMine,
				DummyState
};

BumperState bstate[ 2 ] = { DummyState, MoveOponent};

// Latest target for each bumper, the bumper will try to move through
// this position to hit a puck toward the horizontal center.
Vector2D target[ 2 ];
Vector2D sledPM[ 2 ];

// How much longer the bumper has to pursue its target.  This keeps
// the bumper from chasing after a bad target forever.
int targetTime[ 2 ] = { 0, 0 };
int spreadTime[ 2 ] = { 0, 0 };

int cor = RED;

Vector2D block;
int num;

int n, turnNum;

double normSledDir()
{
				int q;
				double nDir;

				nDir = slist[0].dir;

				while(nDir < 0.0)
								nDir += 2*PI;

				q = nDir / (2*PI);
				while(q > 0)
				{
								nDir -= 2*PI;
								q--;
				}
				if(slist[0].dir == 6.28)
				{
								nDir = 0.0;
				}

				slist[0].dir = nDir;
}

double normSledDir2(double dir)
{
				int q;
				double nDir;

				nDir = dir;

				while(nDir < 0.0) {
								nDir += 2*PI;
				}

				q = nDir / (2*PI);
				while(q > 0)
				{
								nDir -= 2*PI;
								q--;
				}
				if(nDir == 6.28)
				{
								nDir = 0.0;
				}
				return(nDir);
}


/** Return a copy of x that's constrained to be between low and high. */
double clamp( double x, double low, double high )
{
				if ( x < low )
								x = low;
				if ( x > high )
								x = high;
				return x;
}

/** Compute a force vector that can be applied to a bumper to get it
	to run through the given target location.  Pos and vel are the
	bumper's current position and velocity.  Target is the position we
	want to run through and force is a returned vector that will move
	the bumper toward the target.  The function returns true until it
	looks like the next move will take us through the target
	location.  */
bool runTo( Vector2D const &pos,
								Vector2D const &vel, 
								Vector2D const &target, 
								Vector2D &force,
								double epsilon = 0.1 )
{
				// Compute a vector that will move self toward the target point.
				Vector2D direction = target - pos;
				double dist = direction.mag();

				// How much force do we have left to use in the force vector.
				//double resForce = BUMPER_FORCE_LIMIT - force.mag();

				// Normalize the direction we need to move.
				direction = direction.norm();

				// First, cancel out any movement that is perpendicular to the desired
				// movement direction.
				Vector2D perp = Vector2D( -direction.y, direction.x );
				force = -(perp * vel ) * perp;

				// Use all the residual force to move toward the target.
				double resForce = BUMPER_FORCE_LIMIT - force.mag();
				force = force + direction.limit( resForce );

				// See if this move will cross close enough to the target location.
				Vector2D nvel = ( vel + force ).limit( BUMPER_SPEED_LIMIT );
				double t = clamp( ( target - pos ) * nvel / (nvel * nvel), 0, 1 );
				if ( ( pos + t * nvel - target ).mag() < epsilon )
								return true;

				return false;
}

/** Return true if a puck at position pos is the responsibility of the
	bumper with index bdex. */
bool mySide( int bdex, Vector2D pos )
{
				if ( bdex == 0 && pos.y < 330 )
								return true;
				if ( bdex == 1 && pos.y > 470 )
								return true;
				return false;
}

int mostCrowdedBlock(int color, vector< Puck > plist, Vector2D &melhorBloco)
{
				vector<vector<int> > blocos;
				melhorBloco.x = melhorBloco.y = 0;
				int auxX, auxY;
				int numBlocos = FIELD_SIZE / BLOCK_SIZE;
				blocos.resize(numBlocos);

				// inicializando blocos
				for(int i=0; i<numBlocos; i++) {
								blocos[i].resize(numBlocos);
								for(int j=0; j<numBlocos; j++)
												blocos[i][j] = 0;
				}

				for(int i=0; i<plist.size(); i++) {
								auxX = plist[i].pos.x/BLOCK_SIZE;
								auxY = plist[i].pos.y/BLOCK_SIZE;
								if(plist[i].color == color) {
												blocos[auxX][auxY]++;
												//cerr << "AUXX " << plist[i].pos.x <<  " AuxY " << plist[i].pos.y << endl;
												// testa novo melhor bloco
												if(blocos[auxX][auxY] > blocos[melhorBloco.x][melhorBloco.y]) {
																melhorBloco.x = auxX;
																melhorBloco.y = auxY;
												}
								}
				}
				/*cerr << endl;
					if(blocos[melhorBloco.x][melhorBloco.y].count >= 3) {
					cerr << "PASSOU DE 3\n";
					cerr << melhorBloco.x << " " << melhorBloco.y << endl;
					cerr << blocos[melhorBloco.x][melhorBloco.y].count << endl;
					}*/

				return blocos[melhorBloco.x][melhorBloco.y];
}

// **************************************************************
// Le dados da entrada.
void leEntrada()
{
				int n;

				// Read all the puck locations.
				cin >> n;
				plist.resize( n );
				for ( int i = 0; i < n; i++ ) 
				{
								Puck &puck = plist[ i ];
								cin >> puck.pos.x >> puck.pos.y >> puck.vel.x >> puck.vel.y
												>> puck.color;
				}

				// Read all the bumper locations.
				cin >> n;
				blist.resize( n );
				for ( int i = 0; i < n; i++ ) 
				{
								Bumper &bumper = blist[ i ];
								cin >> bumper.pos.x >> bumper.pos.y >> bumper.vel.x >> bumper.vel.y;
				}

				// Read all the sled locations.
				cin >> n;
				slist.resize(n);
				sHist.resize(2);
				for ( int i = 0; i < n; i++ ) 
				{
								Sled &sled = slist[ i ];
								cin >> sled.pos.x >> sled.pos.y >> sled.dir;

								// Just ignore the path history for this sled.
								int m;
								cin >> m;
								sHist[i].resize(m);

								double dummy;
								Vector2D ultimoP;
								cin >> dummy;
								sHist[i][0].x=dummy;
								ultimoP.x=dummy;
								sledPM[i].x=dummy;
								cin >> dummy;
								sHist[i][0].y=dummy;
								ultimoP.y=dummy;
								sledPM[i].y=dummy;

								for ( int j = 1; j < m; j++ ) 
								{
												if(i==1)
												{




																cin >> dummy;
																sHist[i][j].x=dummy;
																if(fabs(ultimoP.x-dummy) > 180){
																				//cerr<<"ultimoP.X:"<< ultimoP.x<<" dummy: "<<dummy<<endl;
																				if(ultimoP.x<dummy){//precisa transformar para coordenadas negativas
																								dummy-=800;
																				}
																				else{//transformar para coordenadas acima de 800
																								dummy+=800;
																				}
																}
																ultimoP.x=dummy;
																sledPM[i].x+=dummy;

																cin >> dummy;
																sHist[i][j].y=dummy;
																if(fabs(ultimoP.y-dummy) > 180){
																				//							cerr<<"ultimoP.Y:"<< ultimoP.x<<" dummy: "<<dummy<<endl;
																				if(ultimoP.y<dummy){//precisa transformar para coordenadas negativas
																								dummy-=800;
																				}
																				else{//transformar para coordenadas acima de 800
																								dummy+=800;
																				}

																}
																ultimoP.y=dummy;
																sledPM[i].y+=dummy;


												}
												else
												{
																cin >> sHist[i][j].x;
																cin >> sHist[i][j].y;
												}
								}
								sledPM[i].x/=m;
								if(sledPM[i].x>=800)
												sledPM[i].x-=800;
								if(sledPM[i].x<0)
												sledPM[i].x+=800;

								sledPM[i].y/=m;
								if(sledPM[i].y>=800)
												sledPM[i].y-=800;	
								if(sledPM[i].y<0)
												sledPM[i].y+=800;
				}
}

// **************************************************************

void calculaBumpers()
{
				if(cor == GREY) {
					block = slist[1].pos;
					cor = GREY;
				}
				// Calculates the most crowded region with my color
				if(bstate[0] == DummyState)
				{
								num = mostCrowdedBlock(RED, plist, block);
								if(num >= 6) {
								// center of the block
									block.x = block.x*BLOCK_SIZE+BLOCK_SIZE/2;
									block.y = block.y*BLOCK_SIZE+BLOCK_SIZE/2;
									cor = RED;
									cerr << "VERMELHO\n";
								}
								else {
									block = slist[1].pos;
									cor = GREY;
									cerr << "CINZA\n";
								}
				}
				// Choose a move for each sled.
				for ( int i = 0; i < 2; i++ )
				{
								Bumper &bumper = blist[ i ];
								Vector2D force( 0, 0 );

								// Choose an up direction for this bumper.
								Vector2D up( 0, i == 0 ? -1 : 1 );

								// If my pucks number in the region is greater than 5 
								//if(num >= 3 && bstate[0] != SpreadMine ) {
								if(  bstate[i] == DummyState ) {
												bstate[ i ] = SearchBlock;
												target[ i ] = block;
												num = 0;
								}

								if ( bstate[ i ] == MoveOponent )
								{
												if ( (sledPM[1] - bumper.pos ).mag() < 50)
												{
																bstate[ i ] = SpreadGray;
																targetTime[ i ] = 0;
												} else
																// Move up and scoot a little to the side to prevent stupid behavior.
																//force = force + BUMPER_FORCE_LIMIT * (enemyS.pos - bumper.pos)/* + Vector2D( 0.01, 0 )*/;
																force = force + BUMPER_FORCE_LIMIT * (sledPM[1] - bumper.pos) + Vector2D( 0.01, 0 );
								}

								// Move right until we ge near the right edge.
								/* if ( bstate[ i ] == SeekRight && bumper.pos.x > 750 ) {
									 bstate[ i ] = SeekLeft;
									 }
								 */
								// Move left until we ge near the left edge.
								/*      if ( bstate[ i ] == SeekLeft && bumper.pos.x < 50 )
												if ( fabs( bumper.pos.y - 400 ) < 50 )
												bstate[ i ] = MoveUp;
												else
												bstate[ i ] = SeekRight;
								 */
								if ( bstate[ i ] == SpreadGray )
								{
												// Go across the field and angle back toward the horizontal center
												// line.
												//      Vector2D across( bstate[ i ] == SeekRight ? 1 : -1, 0 );
												//      Vector2D across=enemyS.pos-bumper.pos;
												Vector2D across=sledPM[1]-bumper.pos;
												//( bstate[ i ] == SeekRight ? 1 : -1, 0 );

												// If we don't have a target, find one.
												if ( targetTime[ i ] <= 0 ) {
																for ( int j = 0; j < plist.size(); j++ )
																				// Find a grey target that on my side of the center line, 
																				// not moving too fast, close to me and kind of in the direction
																				// i'm moving.  Also, make sure it's not too close to the top or
																				// bottom.  Among these pucks, pick the one that's closest to
																				// the direction I should be heading.
																				if ( plist[ j ].color == GREY &&
																												/*mySide( i, plist[ j ].pos ) &&*/
																												plist[ j ].vel.mag() < 1 &&
																												( plist[ j ].pos - bumper.pos ).mag() < 150 &&
																												/* ( plist[ j ].pos - bumper.pos ).norm() * across > 0.6 &&*/
																												/* fabs( plist[ j ].pos.y - 400 ) < 360 &&*/
																												( targetTime[ i ] <= 0 || 
																													( plist[ j ].pos - bumper.pos ).norm() * across >
																													( target[ i ] - bumper.pos ).norm() * across ) ) {
																								// Give 20 turns to hit the puck.
																								targetTime[ i ] = 10;
																								// Hit it on its outside edge to bump it closer to the
																								// center.
																								//target[ i ] = plist[ j ].pos - across * 25 + up * 44;
																								//target[ i ] = plist[ j ].pos - across * 8 + up * 11;
																								target[ i ] = plist[ j ].pos;
																				}
												}

												//        if ( targetTime[ i ] >= 0 ) {
												//          force = force + BUMPER_FORCE_LIMIT * (target[i] - bumper.pos)/* + Vector2D( 0.01, 0 )*/;

												// If w have a target, try to hit it.
												if ( targetTime[ i ] >= 0 ) {
																if ( runTo( bumper.pos, bumper.vel, target[ i ], force ) ) {
																				targetTime[ i ] = 0;
																} else
																				targetTime[ i ] -= 1;
												} else {
																// Otherwise, just move across the field and angle toward
																// the center line a little bit.
																//         force = force + ( across - up * 0.05 ).norm() * BUMPER_FORCE_LIMIT;
																force = force + BUMPER_FORCE_LIMIT * (target[i] - bumper.pos)/* + Vector2D( 0.01, 0 )*/;
												}
												if ( (sledPM[1] - bumper.pos ).mag() > 50)
																bstate[ i ] = MoveOponent;

								}

								// Run to the center of the block
								if ( bstate[ i ] == SearchBlock )
								{
												//runTo( bumper.pos, bumper.vel, target[ i ], force );
												if ( runTo( bumper.pos, bumper.vel, target[ i ], force ) )
												{
												//				if( bumper.pos.x >= ( block.x - BLOCK_SIZE/2 ) &&
												//				 bumper.pos.x < ( block.x + BLOCK_SIZE/2) &&
												//				 bumper.pos.y >= ( block.y - BLOCK_SIZE/2 ) &&
												//				 bumper.pos.y < ( block.y + BLOCK_SIZE/2 ) ) {

																// Give 20 turns to spread the pucks
																if(cor == RED)
																	spreadTime[ i ] = 50;
																else
																	spreadTime[ i ] = 0;
																bstate[ i ] = SpreadMine;
												}
												else if((block - bumper.pos).mag() <= 50) {
													spreadTime[ i ] = 0;
													bstate[ i ] = SpreadMine;
												}
												}

												if ( bstate[ i ] == SpreadMine )
												{
																// Horizontal or vertical direction i'm going
																//Vector2D across;
																//if(bumper.vel.x > bumper.vel.y) {
																//				across.x = bumper.vel.x > 0 ? 1 : -1;
																//				across.y = 0;
																//} else {
																//				across.x = 0;
																//				across.y = bumper.vel.y > 0 ? 1 : -1;
																//}

																//Vector2D acrossH( bumper.vel.x > 0 ? 1 : -1, 0 );

																// If we don't have a target, find one.
																if ( targetTime[ i ] <= 0 ) {
																				for ( int j = 0; j < plist.size(); j++ ) {
																								// Find a puck with my color not moving too fast, close
																								// to me and kind of in the direction i'm moving.  Also,
																								// make sure it's in the region block. Among these pucks,
																								// pick the one that's closest to
																								// the direction I should be heading.
																								Vector2D direc = plist[ j ].pos - bumper.pos;
																								if ( plist[ j ].color == cor &&
																																plist[ j ].vel.mag() < 1 &&
																																direc.mag() < BLOCK_SIZE &&
																																//( plist[ j ].pos - bumper.pos ).norm() * across > 0.6 &&
																																// testa se cosseno do angulo interno eh maior que 0.6
																																( direc * bumper.vel ) / ( direc.mag() * bumper.vel.mag() ) > 0.6 &&
																																plist[ j ].pos.x >= ( block.x - BLOCK_SIZE/2 ) &&
																																plist[ j ].pos.x < ( block.x + BLOCK_SIZE/2) &&
																																plist[ j ].pos.y >= ( block.y - BLOCK_SIZE/2 ) &&
																																plist[ j ].pos.y < ( block.y + BLOCK_SIZE/2 ) &&
																																( targetTime[ i ] <= 0 || 
																																	// troca target se direcao de puck atual menor que target anterior
																																	( direc * bumper.vel ) / ( direc.mag() * bumper.vel.mag() ) >
																																	( ( target[ i ] - bumper.pos ) * bumper.vel ) / ( ( target[i] - bumper.pos ).mag() * bumper.vel.mag()) ) ) {
																												// Give 5 turns to hit the puck.
																												targetTime[ i ] = 5;
																												// Hit it on its outside edge to bump it closer to the
																												// center.
																												//target[ i ] = plist[ j ].pos - across * 8 + up * 11;
																												target[ i ] = plist[ j ].pos;
																								}

																				}
																}
																// If w have a target, try to hit it.
																if ( targetTime[ i ] >= 0 )
																{
																				if ( runTo( bumper.pos, bumper.vel, target[ i ], force ) ) {
																								targetTime[ i ] = 0;
																				} else
																								targetTime[ i ] -= 1;
																} else {
																				// Otherwise, just move across the field and angle toward
																				// the center line a little bit.
																				runTo( bumper.pos, bumper.vel, block, force );
																				//force = force + ( acrossH - up * 0.05 ).norm() * BUMPER_FORCE_LIMIT;
																}

																if( --spreadTime[ i ] <= 0 && targetTime[ i ] <= 0) {
																				bstate[ i ] = DummyState;
																}
												}
												// Output the bumper's move.
												cout << force.x << " " << force.y << " ";
								}
								}

								Vector2D bestRegion()
								{
												/////////////////////////////////////////////////////////////////////
												//INICIO DO CODIGO DE VERDADE, AQUI
												//PROGRAMAR O JOGADOR COMO O JOGADOR VERMELHO
												/////////////////////////////////////////////////////////////////////
												//ESTRATEGIA DA DIVISAO
												vector< vector <Bloco> > blocos; // cria matriz de blocos
												// 800x800 => tamanho da area do jogo
												// TAM_BLOCO definido no Utils.h 
												int NumBlocos = 800 / TAM_BLOCO;
												int index=0;
												// Define tamanho da matriz (NumBloco x NumBloco)
												// e inicializa posicoes com zero
												blocos.resize(NumBlocos);

												for(int i=0; i< blocos.size(); i++)
												{
																blocos[ i ].resize(NumBlocos);

																for(int j; j < blocos[i].size(); j++)
																{
																				blocos.at(i)[ j ].Peso = 0;
																}
												}

												//Coloca os pesos dos blocos
												//Peso consiste numa soma de pucks seus. Se existir algum puck em 
												//algum dos blocos, o valor do bloco se torna negativo.
												for(int i=0; i< plist.size(); i++)
												{
																int auxX, auxY;
																int PesoAux, PesoValor;
																auxX = plist[ i ].pos.x / TAM_BLOCO;
																auxY = plist[ i ].pos.y / TAM_BLOCO;
																PesoAux = plist[ i ].color;


																if(PesoAux == RED)
																{
																				// Peso para suas pecas
																				PesoValor = 5;
																}
																else if (PesoAux == BLUE)
																{
																				// Peso para peças do oponente 
																				PesoValor = -1000;
																}
																else
																{
																				// Peso para pecas cinzas
																				PesoValor = 1;
																}

																// Indexacoes para manter a matriz de acordo com o
																// eixo X,Y do jogador Vermelho (inicio no canto inferior
																// direto)
																blocos[(NumBlocos-1)-auxY][auxX].Peso += PesoValor;
												}

												/////////////////////////////////////////////////////////////////////
												//SELECIONA O BLOCO COM MAIOR PESO
												Vector2D MelhorBloco;
												int MelhorPeso = 0;
												for(int i=0; i<blocos.size(); i++)
												{
																for(int j=0; j<blocos[i].size(); j++)
																{
																				if(blocos[i][j].Peso > MelhorPeso)
																				{
																								MelhorBloco.x = i;
																								MelhorBloco.y = j;
																								MelhorPeso = blocos[i][j].Peso;
																				}
																}
												}

												return(MelhorBloco);
								}

								int close(double cx, double cy, double r)
								{
												int i,j,red,blue,grey;
												double tmpx,tmpy;

												red = blue = grey = 0;

												for(i=0;i<plist.size();i++)
												{
																tmpx = plist[i].pos.x - cx;
																tmpx *= tmpx;

																tmpy = plist[i].pos.y - cy;
																tmpy *= tmpy;

																// It's inside
																if((tmpx + tmpy) < (r*r))
																{
																				if(plist[i].color == RED)
																				{
																								red++;
																				}
																				else if(plist[i].color == BLUE)
																				{
																								blue++;
																				}
																				else if(plist[i].color == GREY)
																				{
																								grey++;
																				}
																}
												}

												if(red && !blue && grey)
																return(1);
												else if(red && blue && (blue > red))
																return(1);
												else
																return(0);
								}

								int changeSledDirection(double x, double y)
								{
												double currentDir,nx,ny,nDir,diff,diff2;
												static int p=0,xunxo=0;;

												if(sledState != GETTING_AWAY_EDGE)
																sledState = CHANGE_DIRECTION;	

												if(xunxo > 10)
												{
																sledDir = 0.0;
																if(sledState != GETTING_AWAY_EDGE)
																				sledState = NOTHING;
																return(1);
												}

												currentDir = slist[0].dir;

												nx = (x - 400.0) - (slist[0].pos.x - 400.0);
												ny = (y - 400.0) - (slist[0].pos.y - 400.0);

												nDir = atan(ny/nx);

												nDir = normSledDir2(nDir);

												diff = nDir - currentDir;

												diff2 = abs(diff);

												if(diff2 < 0.01)
												{
																sledDir = 0;

																//		p++;

																//		if(p > 10);
																//		{
																if(sledState != GETTING_AWAY_EDGE)
																				sledState = NOTHING;
																xunxo = 0;
																return(1);
																//		}
												}

												p=0;

												if(diff < 0.0)
												{
																sledDir = diff;
												}
												else
												{
																sledDir = -1.0 * diff;
												}
												xunxo++;
												/*	// Vira pra direita.
														if(diff2 <= PI)
														{
												// Mesmo quadrante vira pra esquerda.
												if(nDir > currentDir)
												{
												if(diff < 0.0)
												{
												sledDir = 2*PI - diff;
												}
												else
												{
												sledDir = diff;
												}
												}
												else if(diff < 0.0)
												{
												sledDir = diff;
												}
												else
												{
												sledDir = -1.0 * diff;
												}
												}
												// senao, pra esquerda.
												else
												{
												if(nDir < currentDir)
												{
												if(diff < 0.0)
												{
												sledDir = diff;
												}
												else
												{
												sledDir = -1.0 * diff;
												}
												}
												else if(diff < 0.0)
												{
												sledDir = 2*PI - diff;
												}
												else
												{
												sledDir = diff;
												}
												}
												 */
												return(0);
								}

								int getAwayFromEdges()
								{
												// It's near to an edge on the X axis.
												if(slist[0].pos.x < BIGGEST_R || slist[0].pos.x > (800.0 - BIGGEST_R))
												{
																sledState = GETTING_AWAY_EDGE;
												}
												// It's near to an edge on the Y axis.
												else if(slist[0].pos.y < BIGGEST_R || slist[0].pos.y > (800.0 - BIGGEST_R))
												{
																sledState = GETTING_AWAY_EDGE;
												}
												else
												{
																sledState = NOTHING;
																return(1);
												}

												if(sledState == GETTING_AWAY_EDGE)
												{
																if(changeSledDirection(400.0,400.0))
																{
																				sledDir = 0;
																}
												}
												return(0);
								}

								int makeCircle(int loopSize,int direction,int loopGap,int giveUpPos)
								{
												static int posCircle, posGap,p=0,erroRaio;
												static double yStart,x,y=100.0;
												static double r,d;
												static Vector2D center, start;
												double tmpx,tmpy;

												int startup = 12;
												int desiste = 0;

												// First move.
												if ( turnNum < startup ) 
												{
																sledState = CIRCLE;
																// Initially, try to move off-center a little bit.
																if ( turnNum < 6 )
																				sledDir = -0.2;
																else
																				sledDir = 0.2;

																posCircle = 0;
																posGap = 0;
																p = 10;
												}
												// If it's drawing the circle.
												else if(posCircle < loopSize - 1)
												{
																if(posCircle == 0)
																{
																				p++;
																				sledState = CIRCLE;
																				start.x = center.x = slist[0].pos.x;
																				start.y = center.y = slist[0].pos.y;
																}
																else if(posCircle == ((loopSize-1)/2))
																{
																				tmpx = center.x - slist[0].pos.x;
																				tmpy = center.y - slist[0].pos.y;
																				d = sqrt((tmpx*tmpx) + (tmpy*tmpy));
																				r = d/2.0;

																				if(r > BIGGEST_R || r < 0.0)
																								erroRaio = 1;
																				else
																								erroRaio = 0;

																				//cerr << "Raio: [" << r << "]" << endl;

																				center.x = (center.x + slist[0].pos.x) / 2.0;
																				center.y = (center.y + slist[0].pos.y) / 2.0;
																}

																// Verifica se deve desistir a partir da posicao giveUpPos.
																if(erroRaio)
																				desiste = 0;
																else if(posCircle >= giveUpPos)
																{
																				if(close(center.x,center.y,r))
																				{
																								desiste = 0;
																				}
																				else
																				{
																								desiste = 1;
																				}
																}

																// Verifica se desiste.
																if(!desiste)
																{
																				// Drive in a loop most of the time.
																				sledDir = direction * 2 * acos( -1.0 ) / loopSize;

																				if(p < 5)
																				{
																								sledDir = 0.0;
																				}
																				else
																				{
																								posCircle++;
																				}
																}
																// Se desiste.
																else
																{
																				posCircle = loopSize;
																				if(direction == LEFT)
																								sledDir = -0.5;
																				else
																								sledDir = 0.5;
																}
												}
												// If the circle was finished.
												else 
												{
																// Move the loop ahead.
																sledDir = 0;
																posGap++;

																// If the gap step is over, restart values.
																if(posGap == loopGap)
																{
																				sledState = CIRCLE_ENDED;
																				posCircle = 0;
																				posGap = 0;
																				p = 0;
																				return(1);
																}
												}

												return(0);
								}

								int startCircle(int &dir)
								{
												int i,red,blue,grey;

												red = blue = grey = 0;

												for(i=0;i<plist.size();i++)
												{
																if((abs(plist[i].pos.x - slist[0].pos.x) < (BIGGEST_R-1.5)) &&
																								(abs(plist[i].pos.y - slist[0].pos.y) < (BIGGEST_R-1.5)))
																{
																				if(plist[i].color == RED)
																								red++;
																				else if(plist[i].color == BLUE)
																								blue++;
																				else if(plist[i].color == GREY)
																								grey++;

																				if(plist[i].color == RED)
																				{
																								// Ta andando mais na horizontal.
																								if(abs(sHist[0][sHist[0].size()-2].y - slist[0].pos.y) < abs(sHist[0][sHist[0].size()-2].x - slist[0].pos.x))
																								{
																												if(plist[i].pos.y < slist[0].pos.y)
																												{
																																if(sHist[0][sHist[0].size()-2].x < slist[0].pos.x)
																																{
																																				dir = RIGHT;
																																}
																																else
																																{
																																				dir = LEFT;
																																}
																												}
																												else
																												{
																																if(sHist[0][sHist[0].size()-2].x < slist[0].pos.x)
																																{
																																				dir = LEFT;
																																}
																																else
																																{
																																				dir = RIGHT;
																																}
																												}
																								}
																								else
																								{
																												if(plist[i].pos.x < slist[0].pos.x)
																												{
																																if(sHist[0][sHist[0].size()-2].y <=slist[0].pos.y)
																																{
																																				dir = LEFT;
																																}
																																else
																																{
																																				dir = RIGHT;
																																}
																												}
																												else
																												{
																																if(sHist[0][sHist[0].size()-2].y < slist[0].pos.y)
																																{
																																				dir = RIGHT;
																																}
																																else
																																{
																																				dir = LEFT;
																																}
																												}
																								}
																				}
																}
												}
												if(red && !blue && grey)
																return(1);
												else if(red && blue && (blue > red))
																return(1);
												return(0);
								}

								void calculaSleds()
								{
												static Vector2D bestReg;
												static int dir=LEFT,p=0;

												// Normaliza a direcao atual do sled.
												normSledDir();

												// Se por acaso nao faz nada, entao vai reto.
												sledDir = 0;

												//	getAwayFromEdges();

												// Avalia estados do sled.
												if(sledState == NOTHING)
												{
																if(turnNum == 0)
																{
																				dir = LEFT;
																				makeCircle(40,dir,6,22);
																}
																else if(startCircle(dir))
																{
																				makeCircle(40,dir,6,22);
																}
																else if(p == 15)
																{
																				p=0;
																				bestReg = bestRegion();
																				bestReg.x *= TAM_BLOCO;
																				bestReg.y *= TAM_BLOCO;
																				//cerr << "BestRegion = [" << bestReg.x << "," << bestReg.y << "]" << endl;
																				changeSledDirection(bestReg.x,bestReg.y);
																}
																else
																{
																				p++;
																}
												}
												else if(sledState == CIRCLE)
												{
																makeCircle(40,dir,6,22);
												}
												else if(sledState == CIRCLE_ENDED)
												{
																bestReg = bestRegion();
																bestReg.x *= TAM_BLOCO;
																bestReg.y *= TAM_BLOCO;
																//cerr << "BestRegion = [" << bestReg.x << "," << bestReg.y << "]" << endl;
																changeSledDirection(bestReg.x,bestReg.y);
												}
												else if(sledState == CHANGE_DIRECTION)
												{
																changeSledDirection(bestReg.x,bestReg.y);
												}

												// Output the sled's move.
												cout << sledDir << endl;
								}

								int main() {
												cin >> turnNum;

												while ( turnNum >= 0 ) 
												{
																leEntrada();

																calculaBumpers();

																calculaSleds();

																//		changeSledDirection(750.0,0.0);

																cin >> turnNum;
												}
								}
